﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;


namespace cs_modmankey.Views
{


    public enum ModManKeyEvent
    {
        EVT_KEY_DOWN= 0x0001,
        EVT_KEY_UP= 0x0002,
        EVT_CLICK= 0x0101, 
        EVT_DBL_CLICK= 0x0102,   
        EVT_PRESSING= 0x0201,
        EVT_LONG_CLICK=0x2002
    }

    public enum ModManKeyState
    {
        STT_IDLE=0,
        STT_WAITING_CLICK_UP=1,
        STT_WAITING_DBL_CLICK_DOWN =2,
        STT_WAITING_DBL_CLICK_UP=3,
        STT_LONG_PRESSING=10
    }

    public class ModmanBtnRoutedEventArgs: RoutedEventArgs
    {
        public ModManKeyEvent modManKeyEvent { get; set; }
        public ModmanBtnRoutedEventArgs(ModManKeyEvent modEvent,  RoutedEvent routedEvent, object source) : base(routedEvent,source)
        {
            modManKeyEvent = modEvent;
        }
    }

    /// <summary>
    /// ModmanBtn.xaml 的交互逻辑
    /// </summary>
    public partial class ModmanButton : UserControl
    {

        public string Title { get; set; }
        public uint KeyId { get; set; }
        /// <summary>
        /// 按钮电平
        /// </summary>
        public bool keyVal { get; set; }
        /// <summary>
        /// 状态
        /// </summary>
        public ModManKeyState m_state;
        /// <summary>
        /// 按下时间
        /// </summary>
        public long m_downMs;
        /// <summary>
        /// 长按计数
        /// </summary>
        public uint m_pressingCount;

        public static  RoutedEvent userControlClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ModmanButton));

        /// <summary>
        /// 控件点击的事件,用来向外部发消息
        /// </summary>
        public event RoutedEventHandler Click
        {
            add
            {
                AddHandler(userControlClickEvent, value);
            }

            remove
            {
                RemoveHandler(userControlClickEvent, value);
            }
        }

        public string BtnColor
        {
            get
            {
                if (keyVal == true)
                {
                    return "Red";
                }
                else
                {
                    return "White";
                }

            }
        }



        public ModmanButton()
        {
            InitializeComponent();
            this.DataContext = this;
            bt.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.Button_Down), true);
            bt.AddHandler(Button.MouseLeftButtonUpEvent, new MouseButtonEventHandler(this.Button_Up), true);
            keyVal = false;
        }

        bool GetKeyboardMask()
        {
            return keyVal;
        }

       public void OnUiTick(long ms)
        {
            bool keyPressState = GetKeyboardMask();
            switch (m_state)
            {
                case ModManKeyState.STT_IDLE:                                  // 缺省处于空闲状态
                default:
                    if (keyPressState == true)
                    {               // 一切从按下开始
                        m_downMs = ms;
                        PostEvent(KeyId, ModManKeyEvent.EVT_KEY_DOWN);
                        m_state = ModManKeyState.STT_WAITING_CLICK_UP;
                    }
                    break;
                case ModManKeyState.STT_WAITING_CLICK_UP:
                    if (ms - m_downMs > 300)
                    {                   // 超时转到长按状态，同时产生第一个按住事件
                        PostEvent(KeyId, ModManKeyEvent.EVT_PRESSING);
                        m_pressingCount = 1;
                        m_state = ModManKeyState.STT_LONG_PRESSING;
                    }
                    else if (keyPressState == false)
                    {           // 完成一次点击，但需要延迟区分CLICK还是DBL_CLICK
                        m_state = ModManKeyState.STT_WAITING_DBL_CLICK_DOWN;
                    }
                    break;
                case ModManKeyState.STT_WAITING_DBL_CLICK_DOWN:
                    if (ms - m_downMs > 400)
                    {                   // 超出400毫秒没等到第二次按下，判断为CLICK结束，回归空闲
                        PostEvent(KeyId, ModManKeyEvent.EVT_CLICK);
                        PostEvent(KeyId, ModManKeyEvent.EVT_KEY_UP);
                        m_state = ModManKeyState.STT_IDLE;
                    }
                    else if (keyPressState == true)
                    {
                        m_state = ModManKeyState.STT_WAITING_DBL_CLICK_UP;     // 遭遇再次按下，判断为DBL_CLICK，后续DBL_CLICK_UP
                    }
                    break;
                case ModManKeyState.STT_WAITING_DBL_CLICK_UP:
                    if (keyPressState == false)
                    {               // 简单等到再次抬起，结束DBL_CLICK，回归空闲
                        PostEvent(KeyId, ModManKeyEvent.EVT_DBL_CLICK);
                        PostEvent(KeyId, ModManKeyEvent.EVT_KEY_UP);
                        m_state = ModManKeyState.STT_IDLE;
                    }
                    break;
                case ModManKeyState.STT_LONG_PRESSING:
                    if (keyPressState == false)
                    {               // 长按期间等到抬起，结束LONG_CLICK，回归空闲
                        PostEvent(KeyId, ModManKeyEvent.EVT_LONG_CLICK);
                        PostEvent(KeyId, ModManKeyEvent.EVT_KEY_UP);
                        m_state = ModManKeyState.STT_IDLE;
                    }
                    else if (ms - m_downMs > 300 + m_pressingCount * 20)
                    {
                        PostEvent(KeyId, ModManKeyEvent.EVT_PRESSING);
                        m_pressingCount++;
                    }
                    break;
            }

        }



        uint PostEvent(uint srcId, ModManKeyEvent manKeyEvent)
        {
            RoutedEventArgs args = new ModmanBtnRoutedEventArgs(manKeyEvent,userControlClickEvent, this);
            Dispatcher.BeginInvoke(new Action(delegate
            {
                RaiseEvent(args);
            }));
            return 0;
        }

        private void Button_Down(object sender, MouseButtonEventArgs e)
        {
            keyVal = true;
            bt.Background = System.Windows.Media.Brushes.Red;
        }

        private void Button_Up(object sender, MouseButtonEventArgs e)
        {
            keyVal = false;
            bt.Background = System.Windows.Media.Brushes.White;
        }

      
    }
}
